package org.karesz.maven.dao.generic;

import java.io.Serializable;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.karesz.maven.utils.HibernateUtil;

/**
 * 
 * Generic implementation of the interface for Data Access Object. 
 * Contains common persistence methods
 * 
 * 
 * @author Karesz
 *
 */

public class GenericDaoImpl<T, ID extends Serializable> extends HibernateUtil implements GenericDao<T, Serializable>{

	static Logger log = Logger.getLogger(GenericDaoImpl.class.getName());
	private Class<T> persistentClass;
	
	public GenericDaoImpl(Class<T> persistentClass){
		this.persistentClass = persistentClass;
	}
	
	/**
	 * Save model to database
	 * @return void
	 * @param entity class
	 * 
	 */
	
	public void save(T entity) {
		Session session = getSessionFactory().getCurrentSession();
		Transaction tx = null;
	     try{
	    	tx = session.beginTransaction();
			session.save(entity);
			tx.commit();

	      }catch (HibernateException e) {
	         if (tx!=null) tx.rollback();
	         e.printStackTrace();
	         log.error(e.getMessage());
	         
	      }
		
	}
	
	/**
	 * Update model in the database
	 * @return void
	 * @param entity class
	 * 
	 */

	public void update(T entity) {
		Session session = getSessionFactory().getCurrentSession();
		Transaction tx = null;
	     try{
	    	tx = session.beginTransaction();
			session.update(entity);
			tx.commit();

	      }catch (HibernateException e) {
	         if (tx!=null) tx.rollback();
	         e.printStackTrace();
	         log.error(e.getMessage());
	         
	      }
	}

	/**
	 * Delete entity from the database
	 * @return void
	 * @param entity class
	 * 
	 */
	
	public void delete(T entity) {
		Session session = getSessionFactory().getCurrentSession();
		Transaction tx = null;
	     try{
	    	tx = session.beginTransaction();
			session.delete(entity);
			tx.commit();

	      }catch (HibernateException e) {
	         if (tx!=null) tx.rollback();
	         e.printStackTrace();
	         log.error(e.getMessage());
	         
	      }
	}
	
	/**
	 * Get entity by id
	 * @return Entity class
	 * @param Serializable
	 * 
	 */

	public T findById(Serializable id) {
		Session session = getSessionFactory().getCurrentSession();
		session.beginTransaction();
		@SuppressWarnings("unchecked")
		T entity = (T) session.get(this.persistentClass, id);
		session.getTransaction().commit();
		return entity;		
	}

	/**
	 * 
	 * Returns all the records of the entity from the database.
	 * @return List of the entity
	 * 
	 */
	
	public List<T> findAll() {
		Session session = getSessionFactory().getCurrentSession();
		session.beginTransaction();
		@SuppressWarnings("unchecked")
		List<T> list = (List<T>)session.createCriteria(persistentClass).list();
		session.getTransaction().commit();
		return list;
	}




}
